using Godot;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

public abstract partial class BaseAIComponent : Node
{
    protected Robot Self;
    protected static BaseLevelManager LevelManager => GameManager.Instance.LevelManager;
    protected static RobotManager RobotManager => LevelManager.RobotManager;
    protected static Cursor Cursor => LevelManager.Cursor;
    protected static BaseMapManager MapManager => LevelManager.MapManager;
    protected static BattleManager BattleManager => LevelManager.BattleManager;

    public override void _Ready()
    {
        base._Ready();
        Self = GetParent<Robot>();
    }
    public abstract void Run();

    protected List<DamageInfoInBattle> CalculateDamage(Dictionary<WeaponEntity, List<Robot>> dic, Robot attacker)
    {
        var result = new List<DamageInfoInBattle>();
        bool willBreak = false;
        foreach (var item in dic)
        {
            var weapon = item.Key;
            var targets = item.Value;
            foreach (var target in targets)
            {
                var damage = attacker.AttackTarget(target, weapon, true);
                // 如果伤害大于等于目标的生命值 ，找到了可以击杀的机体，直接返回
                if (damage >= target.Entity.CurrentHealth)
                {
                    result.Clear();
                    result.Add(new DamageInfoInBattle
                    {
                        Attacker = attacker,
                        Target = target,
                        Damage = damage,
                        UsedWeapon = weapon,
                    });
                    willBreak = true;
                    break;
                }
                result.Add(new DamageInfoInBattle
                {
                    Attacker = attacker,
                    Target = target,
                    Damage = damage,
                    UsedWeapon = weapon,
                });
            }
            if (willBreak)
            {
                break;
            }
        }
        if (result.Count > 0)
        {
            result.Sort((a, b) => b.Damage - a.Damage);
        }
        return result;
    }

    protected List<DamageInfoInBattle> CalculateDamage(List<Robot> list, Robot attacker)
    {
        var result = new List<DamageInfoInBattle>();
        bool willBreak = false;
        foreach (var wp in attacker.Entity.WeaponList)
        {
            foreach (var target in list)
            {
                var damage = attacker.AttackTarget(target, wp, true);
                // 如果伤害大于等于目标的生命值 ，找到了可以击杀的机体，直接返回
                if (damage >= target.Entity.CurrentHealth)
                {
                    result.Clear();
                    result.Add(new DamageInfoInBattle
                    {
                        Attacker = attacker,
                        Target = target,
                        Damage = damage,
                        UsedWeapon = wp,
                    });
                    willBreak = true;
                    break;
                }
                result.Add(new DamageInfoInBattle
                {
                    Attacker = attacker,
                    Target = target,
                    Damage = damage,
                    UsedWeapon = wp,
                });
            }
            if (willBreak)
            {
                break;
            }
        }
        if (result.Count > 0)
        {
            result.Sort((a, b) => b.Damage - a.Damage);
        }
        return result;
    }

    protected async Task MoveAndAttack(List<MoveGrid> moveArea, Robot attacker, Robot target, WeaponEntity usedWeapon)
    {
        var canAttackArea = MapManager.GetCanAttackTargetArea(target, usedWeapon.RangeMin, usedWeapon.RangeMax);
        // 从可以攻击的范围内找到机体移动范围中存在的区域
        canAttackArea = MapManager.FindSameAreaBetweenAreas(canAttackArea, moveArea);
        if (canAttackArea.Count > 0)
        {
            // 随机取最近的点进行移动
            var area = MapManager.GetNearestPointInArea(target, canAttackArea);
            var p = area[GD.RandRange(0, area.Count - 1)].MapPos;
            await RobotManager.RobotMoveTo(attacker, p);
            await PlayBattleRecord(attacker, target, usedWeapon);
        }
    }

    protected async Task PlayBattleRecord(Robot attacker, Robot target, WeaponEntity wp)
    {
        Cursor.FocusTarget(target);
        await ToSignal(Cursor, nameof(Cursor.CameraMoveEnd));
        BattleManager.StartBattle(attacker, target, wp as WeaponEnemyTarget);
        await ToSignal(BattleManager, nameof(BattleManager.BattleEnd));
    }
    protected async Task MoveToNearEnemy(Robot robot, List<MoveGrid> moveArea)
    {
        // 找到最近的一些敌人
        var nearestTars = RobotManager.GetNearestEnemyRobots(robot);
        if (nearestTars.Count > 0)
        {
            // 找到能造成伤害最大的敌人
            var damageList = CalculateDamage(nearestTars, robot);
            // GD.Print($"{robot.Name} 向最近的敌人 {damageList[0].Target.Name} 移动");
            // 找出移动范围内离敌人最近的几个点
            var tarPos = MapManager.GetNearestPointInArea(damageList[0].Target, moveArea);
            // 随机获取一个点并移动
            var p = tarPos[GameUtil.Random(0, tarPos.Count - 1)].MapPos;
            RobotManager.MoveRobot(p, robot, MapManager);
            await ToSignal(robot, nameof(Robot.OnMoveEnd));
            robot.SetRobotActionEnd();
        }
        else
        {
            robot.SetRobotActionEnd();
        }
    }
}